/**
 * AI Service - Abstraction layer for multiple LLM providers
 * Supports: OpenAI (ChatGPT), Anthropic (Claude), DeepSeek, and custom providers
 */

const { OpenAI } = require('openai');
const Anthropic = require('@anthropic-ai/sdk');
const axios = require('axios');

class AIService {
  constructor(config = {}) {
    this.config = {
      defaultProvider: 'deepseek', // 强制使用deepseek
      ...config
    };
    
    // 确保deepseek提供商始终可用，即使没有环境变量
    this.providers = {
      openai: this._initOpenAI(),
      anthropic: this._initAnthropic(),
      deepseek: {
        apiKey: process.env.DEEPSEEK_API_KEY || 'sk-mock-key',
        baseUrl: process.env.DEEPSEEK_API_URL || 'https://api.deepseek.com'
      }
    };
    
    // 测试DeepSeek连接
    this.testDeepSeekConnection();
  }
  
  /**
   * Initialize OpenAI client
   */
  _initOpenAI() {
    if (!process.env.OPENAI_API_KEY) {
      return null;
    }
    
    return new OpenAI({
      apiKey: process.env.OPENAI_API_KEY
    });
  }
  
  /**
   * Initialize Anthropic client
   */
  _initAnthropic() {
    if (!process.env.ANTHROPIC_API_KEY) {
      return null;
    }
    
    return new Anthropic({
      apiKey: process.env.ANTHROPIC_API_KEY
    });
  }
  
  /**
   * Initialize DeepSeek client
   */
  _initDeepSeek() {
    if (!process.env.DEEPSEEK_API_KEY) {
      console.log('⚠️ DeepSeek API key not found in environment variables');
      return null;
    }
    
    // DeepSeek uses a custom implementation
    return {
      apiKey: process.env.DEEPSEEK_API_KEY,
      baseUrl: process.env.DEEPSEEK_API_URL || 'https://api.deepseek.com'
    };
  }
  
  /**
   * Test DeepSeek API connection
   */
  async testDeepSeekConnection() {
    try {
      console.log('Testing DeepSeek API connection...');
      
      if (!this.providers.deepseek) {
        console.log('⚠️ DeepSeek API is not configured');
        return;
      }
      
      // 增加超时时间到15秒
      const controller = new AbortController();
      const timeoutId = setTimeout(() => controller.abort(), 15000);
      
      // 最多重试3次
      let retryCount = 0;
      const maxRetries = 3;
      let connected = false;
      
      while (retryCount < maxRetries && !connected) {
        try {
          // 使用更简单的请求来减少超时可能性
          const response = await axios.post(
            `${this.providers.deepseek.baseUrl}/v1/chat/completions`,
            {
              model: process.env.DEEPSEEK_MODEL || 'deepseek-coder',
              messages: [
                { role: 'user', content: 'Hi' }
              ],
              max_tokens: 5
            },
            {
              headers: {
                'Authorization': `Bearer ${this.providers.deepseek.apiKey}`,
                'Content-Type': 'application/json'
              },
              signal: controller.signal,
              // 设置请求超时时间
              timeout: 15000
            }
          );
          
          if (response.status === 200) {
            console.log('✅ DeepSeek API连接成功！配置有效，可以用于AI评估');
            console.log(`✅ 使用模型：${process.env.DEEPSEEK_MODEL || 'deepseek-coder'}`);
            connected = true;
            break;
          } else {
            console.log(`⚠️ DeepSeek API返回意外状态码: ${response.status}`);
            retryCount++;
            
            if (retryCount < maxRetries) {
              console.log(`重试连接 (${retryCount}/${maxRetries})...`);
              // 等待1秒后重试
              await new Promise(resolve => setTimeout(resolve, 1000));
            }
          }
        } catch (error) {
          retryCount++;
          
          if (error.name === 'AbortError' || error.code === 'ECONNABORTED') {
            console.log('⚠️ DeepSeek API连接超时');
          } else if (error.response) {
            console.log(`⚠️ DeepSeek API错误: ${error.response.status} - ${error.response.statusText}`);
          } else if (error.request) {
            console.log('⚠️ DeepSeek API未收到响应');
          } else {
            console.log(`⚠️ DeepSeek API连接失败: ${error.message}`);
          }
          
          if (retryCount < maxRetries) {
            console.log(`重试连接 (${retryCount}/${maxRetries})...`);
            // 等待1秒后重试
            await new Promise(resolve => setTimeout(resolve, 1000));
          }
        }
      }
      
      clearTimeout(timeoutId);
      
      if (!connected) {
        console.log(`⚠️ 经过${maxRetries}次尝试后，DeepSeek API连接仍然失败`);
        console.log('继续运行，但不使用DeepSeek API连接');
      }
    } catch (error) {
      console.log('⚠️ DeepSeek API连接测试出错:', error.message);
      console.log('继续运行，但不使用DeepSeek API连接');
    }
  }
  
  /**
   * Evaluate a solution using AI
   * @param {string} pattern - Design pattern name
   * @param {string} challenge - Challenge description
   * @param {string} solution - User's solution
   * @param {string} level - Difficulty level (beginner, intermediate, advanced)
   * @param {string} provider - AI provider to use (optional)
   * @returns {Promise<Object>} - Evaluation result
   */
  async evaluateSolution(pattern, challenge, solution, level, provider = null) {
    // 强制使用deepseek，忽略传入的provider
    const aiProvider = 'deepseek';
    console.log(`使用 ${aiProvider} 评估 ${level} 级别的 ${pattern} 模式解决方案`);
    
    // 创建评估提示
    const prompt = this._createEvaluationPrompt(pattern, challenge, solution, level);
    
    try {
      // 直接使用DeepSeek评估，不做其他检查
      console.log('使用DeepSeek评估解决方案', { pattern, level });
      return await this._evaluateWithDeepSeek(prompt);
    } catch (error) {
      console.error(`AI评估出错 (${aiProvider}):`, error);
      console.log('转为使用默认评估方法');
      return this._evaluateWithDefault(pattern, challenge, solution, level);
    }
  }
  
  /**
   * Create evaluation prompt
   */
  _createEvaluationPrompt(pattern, challenge, solution, level) {
    // 构建用户提供的评估格式
    const basePrompt = `
# 设计模式代码评估Prompt

## 角色设定
你是一位资深的软件架构师和设计模式专家，具有丰富的代码审查和架构设计经验。现在需要对提供的代码进行设计模式实现质量评估。

## 评估任务
请根据指定的设计模式对提供的代码进行全面评估，并按照以下格式返回评估结果：

---

## 评估输入格式
\`\`\`
设计模式：${pattern}
难度级别：${level}
挑战描述：${challenge}
代码：
${solution}
\`\`\`

## 评估输出格式

### 1. 模式匹配分析
- **是否符合指定设计模式**: [是/否]
- **模式识别准确度**: [完全符合/部分符合/不符合]
- **关键特征分析**: 
  - 列出该设计模式的核心要素
  - 分析代码中体现的模式特征
  - 指出缺失或错误实现的部分

### 2. 代码质量评估
**评估级别**: [合格/良好/优秀]

**评估维度**:
- **结构设计** (权重25%): 类/接口设计是否合理
- **实现正确性** (权重30%): 模式实现是否正确完整
- **代码质量** (权重25%): 可读性、可维护性、命名规范
- **最佳实践** (权重20%): 是否遵循该模式的最佳实践

### 3. 详细评估说明

#### 优点分析
- 列出代码中实现得好的方面
- 突出符合设计模式原则的部分
- 赞扬代码质量优秀的地方

#### 不足分析
- 指出违反设计模式原则的地方
- 分析代码质量问题
- 识别潜在的设计缺陷

#### 改进建议
- **必须修改**: 严重影响模式实现的问题
- **建议优化**: 可以提升代码质量的改进点
- **可选增强**: 进一步完善的建议

### 4. 开源框架参考
**优秀实现案例**:
- **框架名称**: [具体开源框架/库名称]
- **实现位置**: [具体类/文件路径]
- **实现特点**: 该实现的优秀之处
- **学习价值**: 可以借鉴的设计思路
- **参考链接**: [GitHub链接或官方文档]

### 5. 评估总结
- **总体评价**: 一句话总结代码质量
- **核心建议**: 最重要的1-2个改进建议
- **学习方向**: 推荐深入学习的相关知识点

最终结果需要转换为简化的JSON格式：

\`\`\`json
{
  "rating": "Satisfactory|Good|Excellent|Unsatisfactory",
  "feedback": "详细的代码评估反馈(中文)",
  "suggestions": "改进建议，每条建议独立成行(中文)",
  "correctPatternUsage": true|false
}
\`\`\`

请确保以上JSON格式正确，并且feedback和suggestions字段为中文内容。
`;

    return basePrompt;
  }
  
  /**
   * Default evaluation method when no AI provider is available
   */
  async _evaluateWithDefault(pattern, challenge, solution, level) {
    console.log('Using default evaluation method');
    
    // 根据模式提供更有针对性的评估
    let rating = 'Satisfactory';
    let feedback = `Your solution has been evaluated without AI assistance. For more accurate evaluation, please configure an AI provider API key. `;
    let correctPatternUsage = true;
    let suggestions = `Consider reviewing the ${pattern} pattern documentation for best practices.`;
    
    // 单例模式评估逻辑
    if (pattern === 'Singleton') {
      if (!solution.includes('private static') || !solution.includes('private constructor')) {
        rating = 'Unsatisfactory';
        correctPatternUsage = false;
        feedback += 'The solution is missing key Singleton pattern elements like private static instance and private constructor.';
      } else if (solution.includes('getInstance') && solution.includes('if') && solution.includes('new')) {
        rating = 'Good';
        feedback += 'The solution correctly implements the Singleton pattern with lazy initialization.';
      } else {
        feedback += 'The solution implements basic Singleton pattern requirements.';
      }
    } 
    // 工厂方法模式评估逻辑
    else if (pattern === 'Factory Method') {
      if (solution.includes('interface') && solution.includes('extends') && solution.includes('new')) {
        rating = 'Good';
        feedback += 'The solution correctly implements the Factory Method pattern with proper inheritance.';
      } else if (solution.includes('class') && solution.includes('new') && solution.includes('return')) {
        feedback += 'The solution implements basic Factory Method pattern requirements.';
      } else {
        rating = 'Unsatisfactory';
        correctPatternUsage = false;
        feedback += 'The solution is missing key Factory Method pattern elements.';
      }
    }
    // 抽象工厂模式评估逻辑
    else if (pattern === 'Abstract Factory') {
      if (solution.includes('interface') && solution.includes('abstract') && solution.includes('family')) {
        rating = 'Good';
        feedback += 'The solution correctly implements the Abstract Factory pattern with proper family of objects.';
      } else if (solution.includes('interface') && solution.includes('class') && solution.includes('new')) {
        feedback += 'The solution implements basic Abstract Factory pattern requirements.';
      } else {
        rating = 'Unsatisfactory';
        correctPatternUsage = false;
        feedback += 'The solution is missing key Abstract Factory pattern elements.';
      }
    }
    // 默认评估
    else {
      feedback += `Basic ${pattern} pattern implementation detected.`;
    }
    
    return {
      rating,
      feedback,
      suggestions,
      correctPatternUsage
    };
  }
  
  /**
   * Evaluate with OpenAI
   */
  async _evaluateWithOpenAI(prompt) {
    try {
      const response = await this.providers.openai.chat.completions.create({
        model: process.env.OPENAI_MODEL || 'gpt-4',
        messages: [
          { role: 'system', content: 'You are an expert software design patterns evaluator.' },
          { role: 'user', content: prompt }
        ],
        temperature: 0.3,
        max_tokens: 1000
      });
      
      const result = response.choices[0].message.content;
      return JSON.parse(result);
    } catch (error) {
      console.error('OpenAI evaluation error:', error);
      throw new Error(`OpenAI evaluation failed: ${error.message}`);
    }
  }
  
  /**
   * Evaluate with Anthropic
   */
  async _evaluateWithAnthropic(prompt) {
    try {
      const response = await this.providers.anthropic.messages.create({
        model: process.env.ANTHROPIC_MODEL || 'claude-3-opus-20240229',
        max_tokens: 1000,
        temperature: 0.3,
        system: 'You are an expert software design patterns evaluator.',
        messages: [
          { role: 'user', content: prompt }
        ]
      });
      
      const result = response.content[0].text;
      return JSON.parse(result);
    } catch (error) {
      console.error('Anthropic evaluation error:', error);
      throw new Error(`Anthropic evaluation failed: ${error.message}`);
    }
  }
  
  /**
   * Evaluate with DeepSeek
   */
  async _evaluateWithDeepSeek(prompt) {
    try {
      console.log('调用DeepSeek API评估解决方案...');
      
      // 真实调用DeepSeek API进行评估，而非返回模拟结果
      const response = await axios.post(
        `${this.providers.deepseek.baseUrl}/v1/chat/completions`,
        {
          model: process.env.DEEPSEEK_MODEL || 'deepseek-coder',
          messages: [
            { role: 'system', content: '你是一位专业的设计模式评估专家，擅长评价代码中的设计模式实现。请按照要求返回有效的JSON格式评估结果。' },
            { role: 'user', content: prompt }
          ],
          temperature: 0.3,
          max_tokens: 2000
        },
        {
          headers: {
            'Authorization': `Bearer ${this.providers.deepseek.apiKey}`,
            'Content-Type': 'application/json'
          },
          timeout: 30000 // 30秒超时
        }
      );
      
      console.log('DeepSeek API响应成功');
      
      // 解析API返回结果
      const responseContent = response.data.choices[0].message.content;
      console.log('DeepSeek原始响应:', responseContent.substring(0, 100) + '...');
      
      try {
        // 尝试提取JSON部分
        let jsonStr = responseContent;
        
        // 如果响应包含Markdown代码块格式，则提取JSON部分
        if (responseContent.includes('```json')) {
          jsonStr = responseContent.split('```json')[1].split('```')[0].trim();
        } else if (responseContent.includes('```')) {
          jsonStr = responseContent.split('```')[1].split('```')[0].trim();
        }
        
        // 寻找可能的JSON对象起始位置
        const jsonStartIndex = jsonStr.indexOf('{');
        if (jsonStartIndex > 0) {
          jsonStr = jsonStr.substring(jsonStartIndex);
        }
        
        // 修复常见的JSON语法错误
        jsonStr = jsonStr.replace(/,\s*}/g, '}') // 移除末尾逗号
                          .replace(/,\s*]/g, ']'); // 移除数组末尾逗号
                          
        console.log('尝试解析JSON:', jsonStr.substring(0, 100) + '...');
        const result = JSON.parse(jsonStr);
        
        // 确保结果包含所有必需字段
        const evaluationResult = {
          rating: result.rating || 'Satisfactory',
          feedback: result.feedback || '您的设计模式实现基本符合要求',
          suggestions: result.suggestions || '考虑添加更详细的注释',
          correctPatternUsage: result.correctPatternUsage !== undefined ? result.correctPatternUsage : true
        };
        
        console.log('DeepSeek评估完成:', evaluationResult.rating);
        return evaluationResult;
      } catch (jsonError) {
        console.error('DeepSeek JSON解析错误:', jsonError);
        throw new Error('DeepSeek返回的结果不是有效的JSON格式');
      }
    } catch (error) {
      console.error('DeepSeek评估错误:', error);
      // 发生错误时返回默认评估而不抛出异常
      return {
        rating: 'Satisfactory',
        feedback: `[DeepSeek API调用失败] 无法通过AI评估您的解决方案。系统使用了默认评估逻辑。您的设计模式实现基本符合要求。错误信息: ${error.message}`,
        suggestions: '考虑添加更详细的注释。\n可以改进错误处理机制。\n思考如何使代码更加模块化。',
        correctPatternUsage: true
      };
    }
  }
  
  /**
   * Generate challenge for a design pattern
   * @param {string} patternName - Design pattern name
   * @param {string} category - Pattern category (Creational, Structural, Behavioral)
   * @param {string} level - Difficulty level (intermediate, advanced)
   * @param {string} provider - AI provider to use (optional)
   * @returns {Promise<Object>} - Challenge data
   */
  async generateChallenge(patternName, category, level, provider = null) {
    const aiProvider = provider || this.config.defaultProvider;
    
    // Check if provider is available
    if (!this.providers[aiProvider]) {
      console.log(`AI provider ${aiProvider} is not configured, cannot generate challenge`);
      throw new Error('AI provider not configured');
    }
    
    // Create prompt for challenge generation
    const prompt = this._createChallengeGenerationPrompt(patternName, category, level);
    
    // Route to appropriate provider
    let result;
    switch (aiProvider) {
      case 'openai':
        result = await this._generateWithOpenAI(prompt);
        break;
      case 'anthropic':
        result = await this._generateWithAnthropic(prompt);
        break;
      case 'deepseek':
        result = await this._generateWithDeepSeek(prompt);
        break;
      default:
        throw new Error('Invalid AI provider');
    }
    
    return result;
  }
  
  /**
   * Create challenge generation prompt
   */
  _createChallengeGenerationPrompt(patternName, category, level) {
    // 根据级别调整提示词
    let levelSpecificInstructions = '';
    if (level === 'intermediate') {
      levelSpecificInstructions = `
For intermediate level:
- The challenge should require more complex implementation than beginner level
- Should test deeper understanding of the pattern's flexibility and applicability
- May require combination with basic OOP principles
- Should focus on proper structure and relationships between components
- Include at least one edge case to handle

对于中级难度：
- 挑战应该比初级难度需要更复杂的实现
- 应该测试对模式灵活性和适用性的更深入理解
- 可能需要与基本面向对象原则结合
- 应关注组件之间的正确结构和关系
- 包含至少一个需要处理的边缘情况
`;
    } else if (level === 'advanced') {
      levelSpecificInstructions = `
For advanced level:
- The challenge should test mastery of the pattern's advanced applications
- Should require consideration of design trade-offs and pattern limitations
- May involve integration with other design patterns where appropriate
- Should address complex real-world scenarios that require sophisticated solutions
- Must consider extensibility, maintainability, and edge cases

对于高级难度：
- 挑战应该测试对模式高级应用的掌握程度
- 应该需要考虑设计权衡和模式局限性
- 可能涉及在适当情况下与其他设计模式的集成
- 应解决需要复杂解决方案的真实世界场景
- 必须考虑可扩展性、可维护性和边缘情况
`;
    }

    return `
You are an expert in software design patterns, particularly the Gang of Four (GoF) 23 design patterns.
Create a ${level} level coding challenge for the ${patternName} design pattern (${category} category).

The challenge should:
1. Be appropriate for the ${level} difficulty level
2. Include a realistic scenario where the ${patternName} pattern would be useful
3. Have clear requirements that guide the implementation
4. Include helpful hints that don't give away the entire solution
5. Be implementable in a reasonable timeframe (30-60 minutes)

${levelSpecificInstructions}

Format your response as JSON with the following structure:
{
  "title": "A concise title for the challenge",
  "description": "A brief description of the challenge (1-2 sentences)",
  "scenario": "A detailed scenario describing the problem to solve (2-4 paragraphs)",
  "requirements": ["List of specific requirements for the solution", "At least 3-5 requirements"],
  "hints": ["Helpful hints for solving the challenge", "2-4 hints that guide without giving away the solution"],
  "sampleSolution": "// A basic skeleton or starting point for the solution, not the complete answer",
  "difficulty": 5,
  "timeLimit": 2400
}

For the difficulty, use a scale of 1-10 where:
- For intermediate level: 4-6
- For advanced level: 7-10

For the timeLimit, specify the estimated time in seconds:
- For intermediate level: around 2400 (40 minutes)
- For advanced level: around 3600 (60 minutes)

Please include both English and Chinese translations for title, description, scenario, requirements and hints.
请为标题、描述、场景、需求和提示同时提供英文和中文翻译。
`;
  }
  
  /**
   * Generate with OpenAI
   */
  async _generateWithOpenAI(prompt) {
    try {
      const response = await this.providers.openai.chat.completions.create({
        model: process.env.OPENAI_MODEL || 'gpt-4',
        messages: [
          { role: 'system', content: 'You are an expert software design patterns challenge creator.' },
          { role: 'user', content: prompt }
        ],
        temperature: 0.7,
        max_tokens: 2000
      });
      
      const result = response.choices[0].message.content;
      return JSON.parse(result);
    } catch (error) {
      console.error('OpenAI generation error:', error);
      throw new Error(`OpenAI generation failed: ${error.message}`);
    }
  }
  
  /**
   * Generate with Anthropic
   */
  async _generateWithAnthropic(prompt) {
    try {
      const response = await this.providers.anthropic.messages.create({
        model: process.env.ANTHROPIC_MODEL || 'claude-3-opus-20240229',
        max_tokens: 2000,
        temperature: 0.7,
        system: 'You are an expert software design patterns challenge creator.',
        messages: [
          { role: 'user', content: prompt }
        ]
      });
      
      const result = response.content[0].text;
      return JSON.parse(result);
    } catch (error) {
      console.error('Anthropic generation error:', error);
      throw new Error(`Anthropic generation failed: ${error.message}`);
    }
  }
  
  /**
   * Generate with DeepSeek
   */
  async _generateWithDeepSeek(prompt) {
    try {
      console.log('调用DeepSeek API生成内容...');
      const response = await axios.post(
        `${this.providers.deepseek.baseUrl}/v1/chat/completions`,
        {
          model: process.env.DEEPSEEK_MODEL || 'deepseek-chat',
          messages: [
            { role: 'system', content: 'You are an expert software design patterns challenge creator. Always respond with valid JSON.' },
            { role: 'user', content: prompt }
          ],
          temperature: 0.7,
          max_tokens: 2000
        },
        {
          headers: {
            'Authorization': `Bearer ${this.providers.deepseek.apiKey}`,
            'Content-Type': 'application/json'
          },
          timeout: 60000 // 增加到60秒
        }
      );
      
      console.log('DeepSeek API响应成功');
      let result = response.data.choices[0].message.content;
      console.log('DeepSeek原始结果:', result.substring(0, 100) + '...');
      
      // 处理可能的不规范JSON
      try {
        // 如果返回的是代码块中的JSON，提取出JSON部分
        if (result.includes('```json')) {
          result = result.split('```json')[1].split('```')[0].trim();
        } else if (result.includes('```')) {
          // 如果有其他代码块，也尝试提取
          result = result.split('```')[1].split('```')[0].trim();
        }
        
        // 寻找可能的JSON对象起始位置
        const jsonStartIndex = result.indexOf('{');
        if (jsonStartIndex > 0) {
          result = result.substring(jsonStartIndex);
        }
        
        // 修复常见的JSON语法错误
        result = result.replace(/\n/g, ' ')  // 移除换行符
                       .replace(/,\s*}/g, '}')  // 移除末尾逗号
                       .replace(/,\s*]/g, ']');  // 移除数组末尾逗号
                       
        console.log('尝试解析JSON:', result.substring(0, 100) + '...');
        return JSON.parse(result);
      } catch (jsonError) {
        console.error('DeepSeek JSON解析错误:', jsonError);
        console.error('接收的内容:', result);
        
        // 创建一个默认的返回对象
        return {
          title: `Challenge for ${prompt.includes('pattern') ? prompt.split('pattern')[1].split(' ')[1] : 'Design Pattern'}`,
          description: "This challenge was created with limited AI assistance.",
          scenario: "Implement the design pattern following best practices.",
          requirements: ["Implement the core components of the design pattern", "Ensure proper structure and relationships", "Demonstrate the pattern's behavior"],
          hints: ["Review the structure of the pattern", "Focus on the relationships between components", "Consider how the pattern solves the problem"],
          sampleSolution: "// Implement the design pattern here",
          difficulty: prompt.includes('intermediate') ? 5 : 8,
          timeLimit: prompt.includes('intermediate') ? 2400 : 3600
        };
      }
    } catch (error) {
      console.error('DeepSeek生成错误:', error);
      throw new Error(`DeepSeek generation failed: ${error.message}`);
    }
  }
}

module.exports = AIService; 